<template>
  <div id="threeDome"></div>
</template>

<script setup>
  import { onMounted } from 'vue'
  // 导入threejs
  import * as THREE from 'three'
  // 导入控制器
  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
  // 导入lil.gui
  import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'

  // 定义需要全局的变量
  let parentMaterial, material, parentCube, cube;

  onMounted(() => {
    initThree()
    initGui()
  })

  const initThree = () => {
    // 创建创景
    const scene = new THREE.Scene()
    // 创建相机
    const camera = new THREE.PerspectiveCamera(
        45, // 视角
        window.innerWidth / window.innerHeight, // 宽高比
        0.1, // 近平面
        1000 // 远平面
    )
    // 创建渲染器
    const renderer = new THREE.WebGLRenderer()
    renderer.setSize(window.innerWidth, window.innerHeight)
    // 添加画布到dom中
    document.querySelector('#threeDome').appendChild(renderer.domElement)

    // 创建立方几何体
    const geometry = new THREE.BoxGeometry(1, 1, 1)
    // 创建材质
    parentMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 })
    material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })

    // 设置父元素材质为线性模式
    parentMaterial.wireframe = true

    // 创建网格（物体）
    parentCube  = new THREE.Mesh(geometry, parentMaterial)
    cube = new THREE.Mesh(geometry, material)
    // 把cube添加到父元素中
    parentCube.add(cube)

    // 设置物体位移(两种方式)，有父元素就是相对父元素偏移，没有父元素相对世界（根元素）偏移
    // cube.position.x = 2
    // cube.position.set(2 , 0, 0)
    // parentCube.position.set(-2, 0, 0)
    cube.position.set(2, 0, 0)

    // 设置物体的缩放(局部放大缩小相对于父元素)
    // parentCube.scale.set(2, 2, 2)
    // cube.scale.set(2, 2, 2)

    // 设置物体绕着x轴旋转(局部旋转，也是相对于父元素)
    parentCube.rotation.x = Math.PI / 4
    cube.rotation.x = Math.PI / 4

    // 将网格添加到场景中
    scene.add(parentCube)

    // 设置相机位置
    camera.position.z = 5
    camera.position.x = 2
    camera.position.y = 2
    // 看向哪里(默认看向原点0)
    camera.lookAt(0, 0, 0)

    // 添加时间坐标辅助器
    const axesHelper = new THREE.AxesHelper(3 )
    // 把坐标器添加到场景中
    scene.add(axesHelper)

    // 添加轨道控制器(加入控制器后模型就可以鼠标拖动了，实际上控制的是相机视角，相机绕着物体旋转)
    const controls = new OrbitControls(camera, renderer.domElement)
    // 设置带阻尼的惯性（拖动后有一个缓动）
    controls.enableDamping = true
    // 设置阻尼系数（就是拖动鼠标松开后惯性的大小，时间长久，数字越小惯性越大）
    controls.dampingFactor = 0.05
    // 利用控制器设置自动旋转
    // controls.autoRotate = true

    // 渲染函数
    function animate() {
      controls.update()
      requestAnimationFrame(animate)
      // 更改网格坐标实现旋转
      // cube.rotation.x += 0.001
      // cube.rotation.y += 0.001
      // 渲染
      renderer.render(scene, camera)
    }
    animate()

    // 监听窗口变化
    window.addEventListener('resize', () => {
      // 重置渲染器宽高比
      renderer.setSize(window.innerWidth, window.innerHeight)
      // 重置相机宽高比和投影矩阵
      camera.aspect = window.innerWidth / window.innerHeight
      // 更新相机投影矩阵
      camera.updateProjectionMatrix()
    })
  }

  const initGui = () => {
    // 创建GUI
    const gui = new GUI()
    // 创建gui按钮
    const eventObj = {
      Fullscreen: function () {
        document.body.requestFullscreen()
      },
      ExitFullscreen: function () {
        if (!document.fullscreenElement) return
        document.exitFullscreen()
      }
    }
    // 添加全屏按钮
    gui.add(eventObj, 'Fullscreen').name('全屏')
    gui.add(eventObj, 'ExitFullscreen').name('退出全屏')
    // 添加控制立方体cube位置的滑块 第一种方法
    // gui.add(cube.position, 'x', -5, 5).name('绿色立方体x轴位置')
    // 添加控制立方体cube位置的滑块 第二种方法 step每次滑动的步长为1
    // gui.add(cube.position, 'x').min(-5).max(5).step(1).name('绿色立方体x轴位置')

    // 添加gui分类(分组) 创建一个名为'绿色立方体'的分组用于绿色立方体xyz轴位置调整
    const cubeFolder = gui.addFolder('绿色立方体')
    // onchange 监听数值改变
    cubeFolder.add(cube.position, 'x').min(-5).max(5).step(1).name('x轴位置').onChange(value => {
      console.log('绿色立方体x轴位置:', value)
    })
    // 监听拖动完成事件，只执行最后一次
    cubeFolder.add(cube.position, 'y').min(-5).max(5).step(1).name('y轴位置')
        // .onFininshChange(value => {
        //   console.log('绿色立方体y轴位置:', value)
        // })
    cubeFolder.add(cube.position, 'z').min(-5).max(5).step(1).name('z轴位置')
    // 添加 设置立方体的材质是否为线性模式
    cubeFolder.add(material, 'wireframe').name('线性模式')
    // 添加颜色选择器
    const colorParams = {
      cubeColor: '#00ff00'
    }
    // 给cube立方体设置颜色
    cubeFolder.addColor(colorParams, 'cubeColor').name('设置颜色').onChange(value => {
      cube.material.color.set(value)
    })


    // 添加gui分类(分组) 创建一个名为'红色立方体'的分组用于红色立方体xyz轴位置调整
    const parentCubeFolder = gui.addFolder('红色立方体')
    parentCubeFolder.add(parentCube.position, 'x').min(-5).max(5).step(1).name('x轴位置')
    parentCubeFolder.add(parentCube.position,'y').min(-5).max(5).step(1).name('y轴位置')
    parentCubeFolder.add(parentCube.position,'z').min(-5).max(5).step(1).name('z轴位置')

    // 添加 设置父元素红色立方体的材质是否为线性模式
    parentCubeFolder.add(parentMaterial, 'wireframe').name('线性模式')
    // 给parentcube立方体设置颜色
    const colorParams2 = {
      cubeColor: '#ff0000'
    }
    parentCubeFolder.addColor(colorParams2, 'cubeColor').name('设置颜色').onChange(value => {
      parentCube.material.color.set(value)
    })

  }




</script>

<style scoped>
  
</style>
